package com.aviation.sell_ticket.config;

import cn.hutool.core.lang.Validator;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.aviation.sell_ticket.tool.Jwt;
import com.aviation.sell_ticket.tool.RedisUtil;
import com.aviation.sell_ticket.tool.ResultEnum;
import com.aviation.sell_ticket.tool.ResultUtil;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class LoginBlocking implements HandlerInterceptor {

	@Resource
	private Jwt jwt;

	@Resource
	private RedisUtil redis;

	/**
	 * 访问控制器方法前执行
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
		try {
			response.setCharacterEncoding("UTF-8");
			response.setContentType("text/html; charset=utf-8");

			//取出请求头中的token,不存在返回登录失效
			String loginKey=request.getHeader("Authorization");
			if(Validator.isNull(loginKey)){
				response.getWriter().write(JSONObject.toJSONString(ResultUtil.success(ResultEnum.ILLEGAL_REQUEST,null)));
				return false;
			}

			//验证token
			DecodedJWT verify= jwt.jwtVerify(loginKey);
			if(verify==null){
				response.getWriter().write(JSONObject.toJSONString(ResultUtil.success(ResultEnum.ILLEGAL_REQUEST,null)));
				return false;
			}

			//取出token中数据，如果为空，此token为伪造token
			String user_id= verify.getClaim("user_idHMAC256").asString();
			if(Validator.isNull(user_id)){
				response.getWriter().write(JSONObject.toJSONString(ResultUtil.success(ResultEnum.ILLEGAL_REQUEST_KQ,null)));
				return false;
			}

			//验证token与服务器token是否一致
			String sessionId=request.getSession().getId();
			String userId=redis.getRedis("UserId:"+user_id);//提取存在redis中的sesseionId
			if(Validator.isNull(userId)){
				response.getWriter().write(JSONObject.toJSONString(ResultUtil.success(ResultEnum.ILLEGAL_REQUEST,null)));
				return false;
			}else if(!userId.equals(sessionId)){
				response.getWriter().write(JSONObject.toJSONString(ResultUtil.success(ResultEnum.ILLEGAL_REQUEST_KQ,null)));
				return false;
			}else{

				String token=redis.getRedis("UserSession:"+userId);
				verify= jwt.jwtVerify(token);
				if(verify==null){
					response.getWriter().write(JSONObject.toJSONString(ResultUtil.success(ResultEnum.ILLEGAL_REQUEST,null)));
					return false;
				}

				String user_id_two= verify.getClaim("user_idHMAC256").asString();
				if(Validator.isNull(user_id_two)){
					response.getWriter().write(JSONObject.toJSONString(ResultUtil.success(ResultEnum.ILLEGAL_REQUEST_KQ,null)));
					return false;
				}else if(!user_id_two.equals(user_id) || !token.equals(loginKey)){
					response.getWriter().write(JSONObject.toJSONString(ResultUtil.success(ResultEnum.ILLEGAL_REQUEST_KQ,null)));
					return false;
				}
				//向此请求添加用户id
				request.setAttribute("userId",user_id_two);
				//刷新token过期时间
				redis.setRidesTime("UserSession:"+userId, token, (long) (60 * 30), TimeUnit.SECONDS);
				redis.setRidesTime("UserId:"+user_id_two,userId, (long) (60 * 30), TimeUnit.SECONDS);
			}
		}catch (Exception e){
			response.getWriter().write(JSONObject.toJSONString(ResultUtil.beDefeated(ResultEnum.UNKNOWN_ERROR)));
			return false;
		}
		return true;
	}

	/**
	 * 访问控制器方法后执行
	 */
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {

	}

	/**
	 * postHandle方法执行完成后执行，一般用于释放资源
	 */
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {

	}
}
